using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace iPhOwa.Exchange
{
	/// <summary>
	/// Facade for authenticating against OWA.
	/// </summary>
	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Owa")]
	public static class OwaAuthenticator
	{
		private static bool CheckCert(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
		{
			return true;
		}

		/// <summary>
		/// Does Forms based authentication with the specified credentials.
		/// </summary>
		[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "owa")]
		[SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.Security.Authentication.AuthenticationException.#ctor(System.String)")]
		public static CookieContainer FormsAuthenticate(Uri owaUri, string userName, string password)
		{
			ServicePointManager.ServerCertificateValidationCallback += CheckCert;

			CookieContainer cookies = new CookieContainer();

			Uri authUri = new Uri(new Uri(owaUri.GetLeftPart(UriPartial.Authority))
			                      , new Uri("/exchweb/bin/auth/owaauth.dll", UriKind.Relative));

			byte[] bytes = Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "destination={0}&username={1}&password={2}"
			                                                    , owaUri, userName, password));

			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(authUri);
			request.Method = "POST";
			request.ContentType = "application/x-www-form-urlencoded";
			request.CookieContainer = new CookieContainer();
			request.ContentLength = bytes.Length;

			using(Stream stream = request.GetRequestStream())
			{
				stream.Write(bytes, 0, bytes.Length);
			}

			using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
			{
				if(response.Cookies.Count < 2)
				{
					throw new AuthenticationException("Login failed. Is the login / password correct?");
				}

				cookies.Add(response.Cookies);
			}

			return cookies;
		}
	}
}